﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XOS_VHD_Tools.VHD;
using System.IO;

namespace XOS_VHD_FAT32
{
    class FATCleaner
    {
        private readonly FAT32Driver _drv;

        public FATCleaner(FAT32Driver driver)
        {
            _drv = driver;
        }

        private List<Directory> _cleaningDirectory = new List<Directory>();

        public void CleanDirectory(Directory dirObj)
        {
            return;
            if (_cleaningDirectory.Contains(dirObj))
            {
                return;
            }

            _cleaningDirectory.Add(dirObj);

            try
            {
                var clustsActive = new List<uint>();

                var activeDirEntries = dirObj.Entries.Cast<FSItem>().OrderBy(t => t.Name).SelectMany(t =>
                    {
                        clustsActive.Add(t.FAT32DirEntry.FirstCluster);
                        return LFN.GetLFNEntries(t.Name, t.ShortName).SelectMany(q => q.ToByteArray()).Concat(t.FAT32DirEntry.ToByteArray());
                    });

                if (dirObj.IsRootDirectory)
                {
                    // we must add VolumeInfo/VolumeLabel files
                    activeDirEntries = dirObj.EnumerateDirEntries().Where(t =>
                          {
                              if (t[0x0b] == 0x0f &&
                                  t[0x0c] == 0x00 &&
                                  BitConverter.ToInt16(t, 0x1A) != 0x00)
                              {
                                  return false;
                              }

                              var attr = (DirEntryAttrib)t[11];
                              return attr == DirEntryAttrib.VolumeLabel ||
                                     attr == (DirEntryAttrib.ReadOnly |
                                              DirEntryAttrib.Hidden |
                                              DirEntryAttrib.System |
                                              DirEntryAttrib.VolumeLabel);
                          }).SelectMany(t => t).Concat(activeDirEntries);
                }

                // searching for '.'/'..' files and adding all of them at the beginning of this dir
                var dirContent = dirObj.EnumerateDirEntries().Where(t => t[0] == '.' && (t[0x0b] != 0x0f ||
                            t[0x0c] != 0x00 ||
                            BitConverter.ToInt16(t, 0x1A) != 0x00)).SelectMany(t =>
                                {
                                    clustsActive.Add(t.ConvertTo<DirEntry>().FirstCluster);

                                    return t;
                                }).Concat(activeDirEntries).ToArray();

                // building map of unused FAT entries
                var clustsAll = dirObj.Entries.Cast<FSItem>().Select(t => t.FAT32DirEntry.FirstCluster).Where(t => t >= 2 & t <= 0x0fffffff);

                var fatChanged = false;
                foreach (var clust in clustsAll.Except(clustsActive.Where(t => t >= 2 && t < 0x0ffffff0)))
                {
                    _drv._fatChain[clust] = 0x00000000;
                    fatChanged = true;
                }

                if (fatChanged)
                {
                    _drv.FlushFAT();
                }
            }
            finally
            {
                _cleaningDirectory.Remove(dirObj);
            }
        }
    }
}
